#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>

#include "hash.h"

struct ListNode {
	ValueType value;
	KeyType key;
	Position next;
};

struct HashTbl {
	int tblSize;
	Position *header;
};

Index Hash(const char* key, int tblSize) {
	Index hashValue = 0;
	while (*key != '\0') {
		hashValue = (hashValue << 5) + (*key++);
	}
	return hashValue % tblSize;
}


PtrToTbl initHashTbl(int tblSize) {
	PtrToTbl tbl;
	tbl = (PtrToTbl) malloc(sizeof(struct HashTbl));
	tbl->tblSize = tblSize;
	tbl->header = (Position)malloc(sizeof(Position) * tblSize);
	if (tbl->header == NULL) {
		perror("out of space");
	}
	return tbl;
}

void insert(PtrToTbl tbl, KeyType key, ValueType value) {
	if (tbl == NULL) perror("NULL tbl");
	Index size = tbl->tblSize;
	Index hash = Hash(key, size);
	printf("key=%s,hash=%d\n", key, hash);
	// create new node


	Position p = tbl->header[hash];
	if (p == NULL) {
		printf("	insert to first node\n");
		tbl->header[hash] = newNode(key, value);
		return;
	}

	while (p != NULL) {
		printf("	currKey=%s,currNodeKey=%s\n", key, p->key);
		if (strcmp(key, p->key) == 0) {
			printf("	same key %s, not insert\n", key);
			return;
		}
		if (p->next == NULL) {
			p->next = newNode(key, value);
			return;
		}
		p = p->next;
	}
}

Position newNode(KeyType key, ValueType value) {
	Position node = (Position) malloc(sizeof(struct ListNode));
	node->next = NULL;
	node->key = key;
	node->value = value;
	return node;
}

Position find(PtrToTbl tbl, KeyType key) {
	if (tbl == NULL) perror("NULL tbl");
	Index size = tbl->tblSize;
	Index hash = Hash(key, size);
	Position p = tbl->header[hash];

	KeyType keyP;
	while (p != NULL) {
		keyP = p->key;
		if (strcmp(key, keyP) == 0)
			return p;
		p = p->next;
	}
	return NULL;
}

ValueType retrieve(Position node) {
	if (node == NULL) perror("NULL tbl");
	return node->value;
}
